﻿using sdkrtv2;
using System;
using System.Collections.Generic;
using Windows.Data.Json;
using XiaoweiV2.ResponseDataTypes;
using XiaoweiVoiceAI.Diagnostics;

namespace XiaoweiV2
{
    public static class ResponseHelper
    {
        public static void DebugKeywordResponse(ulong din, string voice_id, int err, Events evt, WakeupFlag wakeupFlag)
        {

            if (evt == Events.TTS) return;

            string logMessage = $"Keyword evt:{evt}, {(err != 0 ? "has error" : "no error")} " +
                $" Din:{din}, voiceId:{voice_id}, error:{err}, wakeup_flag:{wakeupFlag}";

            Debug.WriteLine(logMessage);
        }

        public static void DebugResponse(ulong din, ResponseData data, SessionType sessionType)
        {
            var skill = data.Param.Skill;
            var lastSkill = data.Param.LastSkill;
            var err = data.Param.ErrorCode;
            //var id = data.Param.VoiceId;
            var ctx = data.Param.Context;
            var requestText = data.Param.RequestText;
            var responseData = data.Param.ResponseData;
            var type = data.Param.ResponseType;
            var intent = data.Param.IntentInfo;
            //var grpSize = state_info.Getresource_groups_size();
            var groups = data.Param.ResourceGroups;
            var hasMore = data.Param.HasMorePlaylist;
            var hasHistoryPlayList = data.Param.HasHistoryPlaylist;
            var isRecovery = data.Param.IsRecovery;
            var isNotify = data.Param.IsNotify;
            var wakeupFlag = data.Param.WakeupFlag;
            var resListType = data.Param.ResourceListType;
            var playBehavior = data.Param.PlayBehavior;
            var controlValue = data.Param.ControlValue;
            var responseText = data.Param.ResponseText;
            var hasMoreUp = data.Param.HasMorePlaylistUp;
            var controlId = data.Param.ControlId;
            var evt = data.Evt;
            var voice_id = data.VoiceId;

            if (evt == Events.TTS) return;

            string logMessage = $"sessionType:{sessionType} evt:{evt}, {(err != 0 ? "has error" : "no error")} \n    ---------------------------------------------------------" +
                $"\n      Din:{din}, voiceId:{voice_id}, controlId:{controlId}, controlValue:{controlValue}, error:{err}, wakeup_flag:{wakeupFlag},  " +
                $"requestTxt:{requestText}, responseTxt:{responseText},responseType:{type}, hasMore:{hasMore}, hasMoreUp:{hasMoreUp}, intent:{intent}, " +
                $"hasHistoryPlayList:{hasHistoryPlayList}, isRecovery:{isRecovery}, isNotify:{isNotify}, resListType:{resListType}, playBehavior:{playBehavior}, " +
                $"ctx.id:{ctx?.Id}, ctx.silent_time:{ctx?.SilentTimeout}, ctx.speak_time:{ctx?.SilentTimeout}, " +
                $"ctx.wakeup_profile:{ctx?.WakeupProfile}, ctx.wakeup_type:{ctx?.WakeupType} " +
                $"\n      skillname:{skill.Name}, skillid:{skill.Id}, skilltype:{skill.Type}, lastSkillname:{lastSkill.Name}, lastskillid:{lastSkill.Id}, lastskilltype:{lastSkill.Type}, " +
                $"response data:{responseData}, extend_info:{data.ExtendInfo}, len:{data.ExtendInfoLen}";

            foreach (var group in groups)
            {
                //logMessage += $"        ResourcesSize:{group.GetResource().Count} \n";
                foreach (var res in group.Resources)
                {
                    logMessage += $"\n         - [format:{res.Format}, id:{res.Id}, content:{res.Content}, extendBuffer:{res.ExtendBuffer}" +
                                  $"playcount:{res.PlayCount}, offset:{res.Offset}]";
                }
            }
            logMessage += $"\n    ----------------- {sessionType} response end ------------- \n";

            Debug.WriteLine(logMessage);
        }


        public static string GetPlayId(ResponseParam response)
        {
            foreach (var group in response.ResourceGroups)
            {
                foreach (var res in group.Resources)
                {
                    if (res.Format == ResourceFormat.Url)
                    {
                        return res.Id;
                    }
                }
            }

            return "";
        }

        public static string GetTTSUrl(ResponseParam response)
        {
            foreach (var group in response.ResourceGroups)
            {
                foreach (var res in group.Resources)
                {
                    if (res.Format == ResourceFormat.File)
                    {
                        return res.Content;
                    }
                }
            }
            return "";
        }

        //public static Command GetCommand(ResponseParam response)
        //{
        //    Command command = new Command()
        //    {
        //        Id = (CommandId)response.ControlId,
        //        Param = response.ControlValue
        //    };
        //    return command;
        //}

        public static bool IsCommand(ResponseParam response)
        {
            return Enum.IsDefined(typeof(CommandId), response.ControlId);
        }

        public static bool HasPlayableResource(ResponseParam response)
        {
            foreach (var group in response.ResourceGroups)
            {
                foreach (var res in group.Resources)
                {
                    if (res.Format == ResourceFormat.Url)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public static IList<MediaExtraInfo> GetExtraInfo(ResponseParam param)
        {
            IList<MediaExtraInfo> list = new List<MediaExtraInfo>();
            foreach (var group in param.ResourceGroups)
            {
                foreach (var resource in group.Resources)
                {
                    if (resource.Format == ResourceFormat.Url)
                    {
                        MediaExtraInfo extra = new MediaExtraInfo()
                        {
                            Id = resource.Id,
                            Url = resource.Content,
                            PlayCount = resource.PlayCount,
                            Offset = resource.Offset
                        };
                        if (JsonObject.TryParse(resource.ExtendBuffer, out JsonObject json))
                        {
                            extra.FromJson(json);
                        }

                        list.Add(extra);
                    }
                }
            }
            return list;
        }

        //===========================================================
        public static void DebugKeywordResponse(ulong din, string voice_id, TXCA_EVENT_CS evt, TXCA_PARAM_RESPONSE_CS state_info)
        {
            var skill = state_info.GetSkillInfo();
            var err = state_info.GetErrorCode();
            var requestText = state_info.Getrequest_text();
            var isRecovery = state_info.Getis_recovery();
            var isNotify = state_info.Getis_notify();
            var wakeupFlag = (WakeupFlag)state_info.Getwakeup_flag();
            var responseText = state_info.Getrsp_text();

            if (evt == TXCA_EVENT_CS.txca_event_on_tts) return;

            string logMessage = $"Keyword evt:{evt} \n    ---------------------------------------------------------" +
                $"\n      Din:{din}, voiceId:{voice_id}, error:{err}, wakeup_flag:{wakeupFlag}";

            logMessage += $"\n    --------------------- Keyword response end ------------------- \n";

            Debug.WriteLine(logMessage);
        }
        public static void DebugResponse(ulong din, string voice_id, TXCA_EVENT_CS evt, TXCA_PARAM_RESPONSE_CS state_info, string extend_info, SessionType sessionType)
        {
            var skill = state_info.GetSkillInfo();
            var lastSkill = state_info.GetLastSkillInfo();
            var err = state_info.GetErrorCode();
            var id = state_info.GetVoiceId();
            var ctx = state_info.Getcontext();
            var requestText = state_info.Getrequest_text();
            var responseData = state_info.Getresponse_data();
            var type = (ResponseType)state_info.Getresponse_type();
            var intent = state_info.Getintent_info();
            var grpSize = state_info.Getresource_groups_size();
            var groups = state_info.Getresource_groups();
            var hasMore = state_info.Gethas_more_playlist();
            var hasHistoryPlayList = state_info.Gethas_history_playlist();
            var isRecovery = state_info.Getis_recovery();
            var isNotify = state_info.Getis_notify();
            var wakeupFlag = (WakeupFlag)state_info.Getwakeup_flag();
            var resListType = (PlaylistType)state_info.Getresource_list_type();
            var playBehavior = (PlaylistAction)state_info.Getplay_behavior();
            var controlValue = state_info.Getcontrol_value();
            var responseText = state_info.Getrsp_text();
            var hasMoreUp = state_info.Gethas_more_playlist_up();
            var controlId = (CommandId)state_info.Getcontrol_id();

            if (evt == TXCA_EVENT_CS.txca_event_on_tts) return;

            string logMessage = $"sessionType:{sessionType} evt:{evt} \n    ---------------------------------------------------------" +
                $"\n      Din:{din}, voiceId:{voice_id}, controlId:{controlId}, controlValue:{controlValue}, error:{err}, wakeup_flag:{wakeupFlag},  " +
                $"requestTxt:{requestText}, responseTxt:{responseText},responseType:{type}, hasMore:{hasMore}, hasMoreUp:{hasMoreUp}, intent:{intent}, " +
                $"hasHistoryPlayList:{hasHistoryPlayList}, isRecovery:{isRecovery}, isNotify:{isNotify}, resListType:{resListType}, playBehavior:{playBehavior}, " +
                $"ctx.id:{ctx?.Getid()}, ctx.silent_time:{ctx?.Getsilent_timeout()}, ctx.speak_time:{ctx?.Getspeak_timeout()}, " +
                $"ctx.wakeup_profile:{ctx?.Getwakeup_profile()}, ctx.wakeup_type:{ctx?.Getwakeup_type()} " +
                $"\n      skillname:{skill.name}, skillid:{skill.id}, skilltype:{skill.type}, lastSkillname:{lastSkill.name}, lastskillid:{lastSkill.id}, lastskilltype:{lastSkill.type}, " +
                $"response data:{responseData}, extend_info:{extend_info}, len:{extend_info.Length}";

            foreach (var group in groups)
            {
                //logMessage += $"        ResourcesSize:{group.GetResource().Count} \n";
                foreach (var res in group.GetResource())
                {
                    logMessage += $"\n         - [format:{res.Getformat()}, id:{res.Getid()}, content:{res.Getcontent()}, extendBuffer:{res.Getextend_buffer()}" +
                                  $"playcount:{res.Getplay_count()}, offset:{res.Getoffset()}]";
                }
            }
            logMessage += $"\n    ----------------- {sessionType} response end ------------- \n";

            Debug.WriteLine(logMessage);
        }
    }
}
